package com.feicheng.service.a;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feicheng.common.exception.SystemException;
import com.feicheng.common.task.Cache;
import com.feicheng.common.util.StringGenerator;
import com.feicheng.persistence.entity.*;
import com.feicheng.persistence.mapper.*;
import com.feicheng.persistence.model.SkjlModel;
import com.feicheng.persistence.service.*;
import com.feicheng.service.AsyncService;
import com.feicheng.wxapi.pay.WxAppPayBean;
import com.feicheng.wxapi.pay.transfer.model.TransferBillsResponse;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

@Service
public class FXyService {

    @Autowired
    IClientService clientService;

    @Autowired
    IAclienttqService aclienttqService;

    @Autowired
    IAmenjinService menjinService;

    @Autowired
    IAkechengService kechengService;

    @Autowired
    IAkechengitemService kechengItemService;

    @Autowired
    IAjiaolianService jiaolianService;

    @Autowired
    IAclientbmService clientbmService;

    @Autowired
    IAhyjlService hyjlService;

    @Autowired
    IAkechengskjlService skjlService;

    @Autowired
    IAclientczService czService;

    @Autowired
    IAjlpjService ajlpjService;

    @Autowired
    IAjiaolianService ajiaolianService;

    @Autowired
    IAmdjlService amdjlService;

    @Autowired
    IAdzService adzService;

    @Autowired
    WxAppPayBean wxAppPayBean;

    @Autowired
    Cache cache;

    @Autowired
    IAstoreService storeService;

    @Autowired
    IAroomService roomService;

    @Autowired
    IAdzService dzService;

    @Autowired
    IAmountService amountService;

    @Autowired
    IAclientczService clientczService;

    @Autowired
    IAhylxService hylxService;

    @Autowired
    IAhylxService iAhylxService;

    @Autowired
    IAfxruleService fxruleService;

    @Autowired
    IAfxjlService fxjlService;

    @Autowired
    AsyncService asyncService;

    private String appid;

    private Integer yj;

    @PostConstruct
    private void init() {
        Asetting asetting = cache.getObject("Asetting", Asetting.class);
        appid = asetting.getCappid();
        yj = asetting.getXyyj();
    }

    public JSONObject yjin(JSONObject param) {
        String clientid = param.getString("clientid");
        Client client = clientService.getById(clientid);
        PrepayWithRequestPaymentResponse prepayData =
                wxAppPayBean.jsapi(
                        StringGenerator.getID("XYYJ"),
                        "押金订单",
                        "/notice-url/"+client.getClientid(),
                        yj,
                        client.getOpenid(),
                        "",
                        appid
                );
        String prepayId = prepayData.getPackageVal().split("=")[1];
        client.setPrepayid(prepayId);
        client.setPrepaydata(JSONObject.toJSONString(prepayData));
        clientService.updateById(client);
        param.put("client", client);
        return param;
    }

    public void afterYjin(String clientid) {
        Client client = clientService.getById(clientid);
        client.setYj(yj);
        clientService.updateById(client);
    }

    @Transactional
    public JSONObject yjout(JSONObject param) {
        String clientid = param.getString("clientid");
        Client client = clientService.getById(clientid);
        client.setYj(0);
        clientService.updateById(client);
        Amount amount = amountService.getById(client.getOpenid());
        amount.setAmount(amount.getAmount() + yj);
        amountService.updateById(amount);
        return param;
    }

    @Transactional
    public synchronized void wcHy() {
        LocalDate now = LocalDate.now();
        QueryWrapper<Ahyjl> qw = new QueryWrapper<>();
        qw.eq("stu", "R");
        qw.lt("ed", now);
        List<Ahyjl> ahyjls = hyjlService.list(qw);
        ahyjls.forEach(hy -> {
            hy.setStu("F");
            hyjlService.updateById(hy);
        });
    }

    /**
     * 提款记录分页查询
     * @param param
     * @return
     */
    public JSONObject getTqBypage(JSONObject param) {

        Integer current = param.getInteger("current");
        Integer size = param.getInteger("size");

        if (null == current || current < 0) {
            current = 1;
        }

        if (null == size || size < 0) {
            size = 16;
        }

        IPage<JSONObject> page = new Page<JSONObject>(current , size);
        QueryWrapper<JSONObject> qw = new QueryWrapper<>();
        String clientid = param.getString("clientid");
        if (StringUtils.hasLength(clientid)) {
            qw.eq("aclienttq.clientid", clientid);
        }
        AclienttqMapper aclienttqMapper = (AclienttqMapper)aclienttqService.getBaseMapper();
        page = aclienttqMapper.getTqWithClient(page,qw);
        param.put("aclienttqs", page);
        return param;
    }

    public void tqAfter(String tqjlid, String statu) {
        Aclienttq aclientztq = aclienttqService.getById(tqjlid);
        aclientztq.setZt(statu);
        aclienttqService.updateById(aclientztq);
    }

    /**
     * 新增提款记录
     * @param param
     * @return
     */
    @Transactional
    public JSONObject newTq(JSONObject param) {

        Aclienttq aclienttq = param.getObject("aclienttq", Aclienttq.class);
        Client client = clientService.getById(aclienttq.getClientid());
        Amount amount = amountService.getById(client.getOpenid());
        aclienttq.setTqjlid(StringGenerator.getID("CLTQ"));
        //提取时间
        aclienttq.setCt(LocalDateTime.now());
        //状态
        aclienttq.setZt("R"); //R:已提取；F:已到账；
        //店长提款抽成比例
        Asetting asetting = cache.getObject("Asetting", Asetting.class);
        Double tkCcbl = asetting.getCper();
        aclienttq.setCcbl(tkCcbl);
        aclienttq.setSjje(new BigDecimal(aclienttq.getAmount()).multiply(new BigDecimal(1 - tkCcbl)).intValue());

        amount.setAmount(amount.getAmount() - aclienttq.getSjje());
        amountService.updateById(amount);
        param.put("amount", amount);

        TransferBillsResponse res =
                wxAppPayBean.transferBill(
                        appid,
                        aclienttq.getTqjlid(),
                        "",
                        client.getOpenid(),
                        aclienttq.getSjje(),
                        "备注现金赔付",
                        "/tran-bill/"+aclienttq.getTqjlid(),
                        "");
        JSONObject obj = new JSONObject();
        obj.put("packageInfo", res.getPackageInfo());
        obj.put("mid", wxAppPayBean.getMerchantId());
        obj.put("appid", appid);
        aclienttq.setTres(obj.toJSONString());
        aclienttqService.save(aclienttq);
        param.put("aclienttq", aclienttq);
        return param;
    }

    /**
     * 学员扫脸接口
     * @param param
     * @return
     */
    public JSONObject sl(JSONObject param) {
        String clientid = param.getString("clientid");
        String mjid = param.getString("mjid");

        if (!StringUtils.hasLength(clientid)) {
            throw new SystemException(clientid + "：客户没有被找到");
        }

        if (!StringUtils.hasLength(mjid)) {
            throw new SystemException(mjid + "：门禁没有被找到");
        }
        Amenjin menjin = menjinService.getById(mjid);

        String roomid = param.getString("roomid");
        String storeid = param.getString("storeid");
        if (!StringUtils.hasLength(roomid)) {
            roomid = menjin.getUkey();
            storeid = menjin.getStoreid();
        }

        if (!StringUtils.hasLength(storeid)) {
            storeid = param.getString("storeid");
        }

        LocalTime st = LocalTime.now().plusMinutes(5);
        LocalTime et = LocalTime.now().minusMinutes(5);

        QueryWrapper<SkjlModel> skjlqw = new QueryWrapper<>();
        skjlqw.eq("akechengskjl.clientid", clientid);
        skjlqw.eq("akechengskjl.dt", LocalDate.now());

        if (StringUtils.hasLength(roomid)) {
            skjlqw.eq("akechengitem.roomid", roomid);
        }

        skjlqw.eq("akechengitem.storeid", storeid);
        skjlqw.le("akechengskjl.st", st);
        skjlqw.ge("akechengskjl.et", et);
        AkechengskjlMapper skjlMapper = (AkechengskjlMapper) skjlService.getBaseMapper();
        List<SkjlModel> skjlModelList = skjlMapper.getSkjlWithKcitem(skjlqw);
        if (skjlModelList.size() > 0) {
            SkjlModel skjlModel = skjlModelList.get(0);
            Akechengskjl skjl = new Akechengskjl();
            skjl.setSkjlid(skjlModel.getSkjlid());
            /* 出门 */
            if (menjin.getFlg()) {
                skjl.setStu("ED");
                /* 进门 */
            } else {
                skjl.setStu("ST");
            }
            skjlService.updateById(skjl);

        } else {

            /* 出门 */
            if (menjin.getFlg()) {
            /* 进门 */
            } else {
                throw new SystemException(clientid + "：当前没有课程；无权进入房间【"+roomid);
            }

        }
        return param;
    }



    /**
     * 报名分页查询
     * @param param
     * @return
     */
    public JSONObject getBmByPage(JSONObject param) {
        Integer current = param.getInteger("current");
        Integer size = param.getInteger("size");

        if (null == current || current < 0) {
            current = 1;
        }

        if (null == size || size < 0) {
            size = 16;
        }

        IPage<JSONObject> page = new Page<JSONObject>(current, size);

        QueryWrapper<JSONObject> qw = new QueryWrapper<>();
        String clientid = param.getString("clientid");
        if (StringUtils.hasLength(clientid)) {
            qw.eq("aclientbm.clientid", clientid);
        }
        /** 提取记录id查询 **/
        String tqjlid = param.getString("tqjlid");
        if (StringUtils.hasLength(tqjlid)) {
            qw.eq("ajiaoliantq.tqjlid", tqjlid);
        }

        String jlid = param.getString("jlid");
        if (StringUtils.hasLength(jlid)) {
            qw.eq("aclientbm.jlid", jlid);
        }

        // shihuijun star
        //根据课程名称、教练名称、客户昵称查询
        String kcmc = param.getString("kcmc");
        String jlmc = param.getString("jlmc");
        String khnc = param.getString("khnc");
        boolean hasSearchCondition = StringUtils.hasLength(kcmc) || StringUtils.hasLength(jlmc) || StringUtils.hasLength(khnc);
        if (hasSearchCondition){
            qw.and(qww ->{
                if (StringUtils.hasLength(kcmc)) {
                    qww.like("aclientbm.kcmc", kcmc);
                }
            }).or(qww ->{
                if (StringUtils.hasLength(jlmc)) {
                    qww.like("aclientbm.jlmc", jlmc);
                }
            }).or(qww ->{
                if (StringUtils.hasLength(khnc)) {
                    qww.like("aclientbm.khnc", khnc);
                }
            });
        }
        // shihuijun end

        AclientbmMapper aclientbmMapper =
                (AclientbmMapper) clientbmService.getBaseMapper();

        page = aclientbmMapper.getBmWithJlKcByPage(page, qw);
        param.put("aclientbms", page);
        return param;
    }

    /**
     * 新增会员接口
     * @param param
     * @return
     */
    @Transactional
    public JSONObject newHy(JSONObject param) {

        String hylxid = param.getString("hylxid");
        String clientid = param.getString("clientid");
        String jlid = param.getString("jlid");

        Client client = clientService.getById(clientid);
        Ahylx ahylx = iAhylxService.getById(hylxid);
        Ajiaolian ajiaolian = jiaolianService.getById(jlid);

        Ahyjl ahyjl = new Ahyjl();
        ahyjl.setHyjlid(StringGenerator.getID("HY"));
        ahyjl.setCd(LocalDate.now());
        ahyjl.setClientid(clientid);
        ahyjl.setHylxid(hylxid);
        ahyjl.setPflg(false);
        ahyjl.setTkflg("U");
        ahyjl.setStu("U");
        ahyjl.setAmount(ahylx.getAmount());
        ahyjl.setCs(ahylx.getCs());
        ahyjl.setJlid(jlid);
        ahyjl.setZq(ahylx.getZq());
        ahyjl.setSycs(ahylx.getCs());

        Amount amount = amountService.getById(client.getOpenid());

        if (ahyjl.getAmount() > amount.getAmount()) {
            ahyjl.setYezfje(amount.getAmount().intValue());
            ahyjl.setAmount(ahyjl.getAmount() - amount.getAmount());
            amount.setAmount(0);
            amountService.updateById(amount);
        } else {
            ahyjl.setYezfje(ahyjl.getAmount().intValue());
            amount.setAmount(amount.getAmount() - ahyjl.getAmount());
            ahyjl.setAmount(0);
            amountService.updateById(amount);
        }

        if (ahyjl.getAmount() > 0) {
            PrepayWithRequestPaymentResponse prepayData =
                    wxAppPayBean.jsapi(
                            ahyjl.getHyjlid(),
                            "会员订单",
                            "/notice-url/"+ahyjl.getHyjlid(),
                            ahyjl.getAmount(),
                            client.getOpenid(),
                            "",
                            appid
                    );
            String prepayId = prepayData.getPackageVal().split("=")[1];
            ahyjl.setPrepaydata(JSONObject.toJSONString(prepayData));
            ahyjl.setPrepayid(prepayId);
        }

        hyjlService.save(ahyjl);
        param.put("ahyjl", ahyjl);

        return param;
    }

    @Transactional
    public void payHyAfter(String hyjlid) {
        Ahyjl ahyjl = hyjlService.getById(hyjlid);
        ahyjl.setPflg(true);
        hyjlService.updateById(ahyjl);

        Ajiaolian ajiaolian = jiaolianService.getById(ahyjl.getJlid());
        Amount amount = amountService.getById(ajiaolian.getOpenid());
        amount.setAmount(amount.getAmount() + ahyjl.getAmount());

    }

    /**
     * 报名
     * @param param
     * @return
     */
    @Transactional
    public JSONObject bm(JSONObject param) {
        String clientid = param.getString("clientid");
        if (!StringUtils.hasLength(clientid)) {
            throw new SystemException("必须指定客户");
        }
        String kcid = param.getString("kcid");
        if (!StringUtils.hasLength(kcid)) {
            throw new SystemException("必须指定课程");
        }


        QueryWrapper<Aclientbm> bmqw = new QueryWrapper<>();
        bmqw.eq("clientid", clientid);
        bmqw.eq("kcid", kcid);
        bmqw.ne("stu", "C");
        Long bmcount = clientbmService.count(bmqw);
        if (bmcount > 0) {
            throw new SystemException("您已经报过名了");
        }

        Akecheng akecheng = kechengService.getById(kcid);
        Integer ybrs = akecheng.getYbrs();
        Integer zdrs = akecheng.getZdrs();

            if (ybrs == zdrs) {
                throw new SystemException("当前课程人数已满");
            }

        Client client = clientService.getById(clientid);
        Amount amount = amountService.getById(client.getOpenid());

        Ajiaolian ajiaolian = jiaolianService.getById(akecheng.getJlid());
        QueryWrapper<Akechengitem> qwki = new QueryWrapper<>();
        qwki.eq("kcid", kcid);
        List<Akechengitem> kcitems = kechengItemService.list(qwki);

        synchronized (kcid.intern()) {
            Aclientbm bm = new Aclientbm();
            bm.setBmid(StringGenerator.getID("BM"));
            bm.setKcid(kcid);
            bm.setKcmc(akecheng.getKcname());
            bm.setJlid(akecheng.getJlid());
            bm.setJlmc(ajiaolian.getJlname());
            bm.setClientid(clientid);
            bm.setKhnc(client.getNc());
            bm.setCt(LocalDateTime.now());
            bm.setPflg(false);
            bm.setPrice(akecheng.getPrice());
            bm.setSyhycs(0);
            bm.setYezfje(0);
            bm.setSjzfje(akecheng.getPrice());

            LinkedList<Akechengskjl> skjls = new LinkedList<>();
            for (Akechengitem item : kcitems) {
                Akechengskjl skjl = new Akechengskjl();
                skjl.setSkjlid(StringGenerator.getID("SKJL"));
                skjl.setDt(item.getDt());
                skjl.setSt(item.getSt());
                skjl.setEt(item.getEt());
                skjl.setCt(LocalDateTime.now());
                skjl.setClientid(bm.getClientid());
                skjl.setBmid(bm.getBmid());
                skjl.setKcitemid(item.getKcitemid());
                skjl.setStu("UD");
                skjls.add(skjl);
            }

            List<Akechengskjl> toSkjls = new ArrayList<>();
            // 检查会员次数  课时数-会员次数 = 学员支付报名金额
            // 所以上课记录要标记是使用会员次数结算还是金额结算 取消时会退还会员次数和金额
            QueryWrapper<Ahyjl> hyjlqw = new QueryWrapper<>();
            hyjlqw.eq("clientid", bm.getClientid());
            hyjlqw.eq("jlid", bm.getJlid());
            hyjlqw.and(q -> {
                q.or(q1 -> {
                    q1.or().isNotNull("sd").le("sd", LocalDate.now()).isNotNull("ed").ge("ed", LocalDate.now());
                });

                q.or(q1 -> {
                    q1.or().isNull("sd").isNull("ed");
                });


            });
            hyjlqw.eq("tkflg", "U");
            hyjlqw.gt("sycs", 0);
            hyjlqw.ne("stu", "F");

            List<Ahyjl> hyjls = hyjlService.list(hyjlqw);

            BigDecimal dj =
                    new BigDecimal(akecheng.getPrice()).divide(new BigDecimal(kcitems.size()), 0, RoundingMode.HALF_UP);

            if (null != hyjls && hyjls.size() > 0) {
                for (Ahyjl hyjl : hyjls) {
                    if ((hyjl.getCs().intValue() == hyjl.getSycs().intValue()) && "U".equals(hyjl.getStu())) {
                        hyjl.setSd(LocalDate.now());
                        hyjl.setEd(LocalDate.now().plusDays(hyjl.getZq()));
                        hyjl.setStu("R");
                        hyjlService.updateById(hyjl);
                    }

                    while (skjls.size() > 0) {
                        if (hyjl.getSycs().intValue() > 0) {
                            Akechengskjl akechengskjl = skjls.removeFirst();
                            akechengskjl.setHyjlid(hyjl.getHyjlid());
                            hyjl.setSycs(hyjl.getSycs() - 1);
                            bm.setSjzfje(bm.getSjzfje() - dj.intValue());
                            bm.setSyhycs(bm.getSyhycs() + 1);
                            toSkjls.add(akechengskjl);
                        } else {
                            hyjl.setStu("F");
                            break;
                        }
                    }

                    hyjlService.updateById(hyjl);

                    if (skjls.size() == 0) {
                        break;
                    }


                }
            } else {
                toSkjls.addAll(skjls);
            }

            skjlService.saveBatch(toSkjls);

            if (bm.getSjzfje() > 0) {

                /* 余额充足，不支付 */
                if (bm.getSjzfje() <= amount.getAmount()) {
                    amount.setAmount(amount.getAmount() - bm.getSjzfje());
                    bm.setYezfje(bm.getSjzfje());
                    bm.setSjzfje(0);
                    bm.setPflg(true);

                    /* 余额不充足，支付 */
                } else {
                    bm.setSjzfje(bm.getSjzfje() - amount.getAmount());
                    bm.setYezfje(amount.getAmount());
                    amount.setAmount(0);
                    PrepayWithRequestPaymentResponse prepayData =
                            wxAppPayBean.jsapi(
                                    bm.getBmid(),
                                    "报名订单",
                                    "/notice-url/" + bm.getBmid(),
                                    bm.getSjzfje(),
                                    client.getOpenid(),
                                    "",
                                    appid
                            );
                    String prepayId = prepayData.getPackageVal().split("=")[1];
                    bm.setPrepaydata(JSONObject.toJSONString(prepayData));
                    bm.setPrepayid(prepayId);
                }

                amountService.updateById(amount);
            }

            if (ybrs < zdrs) {
                bm.setStu("B");
            } else if (ybrs >= zdrs) {
                bm.setStu("P");
                bm.setSort(ybrs - zdrs + 1);
            }
            ybrs++;
            akecheng.setYbrs(ybrs);
            kechengService.updateById(akecheng);

            if (StringUtils.hasLength(client.getFromid()) && !client.getTgflg()) {

                Client fromClient = clientService.getById(client.getFromid());

                Integer ruleid = fromClient.getTgcount() % 3 + 1;
                fromClient.setTgcount(fromClient.getTgcount() + 1);
                clientService.updateById(fromClient);

                JSONObject ruleObj = cache.getJSONObject("FXRULE");
                Afxrule rule = ruleObj.getObject(String.valueOf(ruleid), Afxrule.class);

                Afxjl afxjl = new Afxjl();
                afxjl.setFxjlid(StringGenerator.getID("FX"));
                afxjl.setBmid(bm.getBmid());
                afxjl.setCt(LocalDateTime.now());
                afxjl.setTqper(rule.getTqper());
                afxjl.setAmount(bm.getPrice());
                afxjl.setFxje(new BigDecimal(bm.getPrice()).multiply(new BigDecimal(rule.getTqper())).intValue());
                afxjl.setClientid(clientid);
                afxjl.setFxjlid(bm.getJlid());
                afxjl.setFxclientid(fromClient.getClientid());
                afxjl.setStu("T");
                afxjl.setLevel(rule.getLevel());
                fxjlService.save(afxjl);

                bm.setFxjlid(afxjl.getFxjlid());
                bm.setFxje(afxjl.getFxje());

            }

            clientbmService.save(bm);
            param.put("aclientbm", bm);

            asyncService.runScheduler(() -> {
                synchronized (bm.getBmid().intern()) {
                    Aclientbm aclientbmCheck = clientbmService.getById(bm.getBmid());
                    if (!aclientbmCheck.getPflg()) {
                        cancelBm(aclientbmCheck);
                        return "未支付，报名取消";
                    }
                    return "已支付，报名成功";
                }

            }, 2, "报名支付核减：【"+bm.getBmid()+"】");
        }

        return param;

    }

    @Transactional
    public void payBmAfter(String bmid) {
        Aclientbm aclientbm = clientbmService.getById(bmid);
        aclientbm.setPflg(true);
        String kcid = aclientbm.getKcid();

        synchronized (kcid.intern()) {
            Akecheng akecheng = kechengService.getById(kcid);
            Integer ybrs = akecheng.getYbrs();
            Integer zdrs = akecheng.getZdrs();

            if (ybrs < zdrs) {
                aclientbm.setStu("B");
            } else if (ybrs >= zdrs) {
                aclientbm.setStu("P");
                aclientbm.setSort(ybrs - zdrs + 1);
            }
            akecheng.setYbrs(ybrs++);
            clientbmService.updateById(aclientbm);
            kechengService.updateById(akecheng);
        }

    }



    /**
     * 报名
     * @param param
     * @return
     */
    @Transactional
    public JSONObject zybm(JSONObject param) {
        String clientid = param.getString("clientid");
        if (!StringUtils.hasLength(clientid)) {
            throw new SystemException("必须指定客户");
        }
        String kcid = param.getString("kcid");
        if (!StringUtils.hasLength(kcid)) {
            throw new SystemException("必须指定课程");
        }


        QueryWrapper<Aclientbm> bmqw = new QueryWrapper<>();
        bmqw.eq("clientid", clientid);
        bmqw.eq("kcid", kcid);
        bmqw.ne("stu", "C");
        Long bmcount = clientbmService.count(bmqw);
        if (bmcount > 0) {
            throw new SystemException("您已经报过名了");
        }

        Akecheng akecheng = kechengService.getById(kcid);
        Integer ybrs = akecheng.getYbrs();
        Integer zdrs = akecheng.getZdrs();

        if (ybrs == zdrs) {
            throw new SystemException("当前课程人数已满");
        }

        Client client = clientService.getById(clientid);
        Amount amount = amountService.getById(client.getOpenid());

        Amdjl amdjl = amdjlService.getById(akecheng.getMdjlid());
        QueryWrapper<Akechengitem> qwki = new QueryWrapper<>();
        qwki.eq("kcid", kcid);
        List<Akechengitem> kcitems = kechengItemService.list(qwki);

        synchronized (kcid.intern()) {
            Aclientbm bm = new Aclientbm();
            bm.setBmid(StringGenerator.getID("BMZY"));
            bm.setKcid(kcid);
            bm.setKcmc(akecheng.getKcname());
            bm.setMdjlid(akecheng.getMdjlid());
            bm.setJlmc(amdjl.getMdjlname());
            bm.setClientid(clientid);
            bm.setKhnc(client.getNc());
            bm.setCt(LocalDateTime.now());
            bm.setPflg(false);
            bm.setPrice(akecheng.getPrice());
            bm.setSyhycs(0);
            bm.setYezfje(0);
            bm.setSjzfje(akecheng.getPrice());

            LinkedList<Akechengskjl> skjls = new LinkedList<>();
            for (Akechengitem item : kcitems) {
                Akechengskjl skjl = new Akechengskjl();
                skjl.setSkjlid(StringGenerator.getID("SKJL"));
                skjl.setDt(item.getDt());
                skjl.setSt(item.getSt());
                skjl.setEt(item.getEt());
                skjl.setCt(LocalDateTime.now());
                skjl.setClientid(bm.getClientid());
                skjl.setBmid(bm.getBmid());
                skjl.setKcitemid(item.getKcitemid());
                skjl.setStu("UD");
                skjls.add(skjl);
            }

            List<Akechengskjl> toSkjls = new ArrayList<>();
            // 检查会员次数  课时数-会员次数 = 学员支付报名金额
            // 所以上课记录要标记是使用会员次数结算还是金额结算 取消时会退还会员次数和金额
            QueryWrapper<Ahyjl> hyjlqw = new QueryWrapper<>();
            hyjlqw.eq("clientid", bm.getClientid());
            hyjlqw.eq("jlid", bm.getMdjlid());
            hyjlqw.and(q -> {
                q.or(q1 -> {
                    q1.or()
                            .isNotNull("sd")
                            .le("sd", LocalDate.now())
                            .isNotNull("ed")
                            .ge("ed", LocalDate.now());
                });

                q.or(q1 -> {
                    q1.or().isNull("sd").isNull("ed");
                });


            });
            hyjlqw.eq("tkflg", "U");
            hyjlqw.gt("sycs", 0);
            hyjlqw.ne("stu", "F");

            List<Ahyjl> hyjls = hyjlService.list(hyjlqw);

            BigDecimal dj =
                    new BigDecimal(akecheng.getPrice()).divide(new BigDecimal(kcitems.size()), 0, RoundingMode.HALF_UP);

            if (null != hyjls && hyjls.size() > 0) {
                for (Ahyjl hyjl : hyjls) {
                    if ((hyjl.getCs().intValue() == hyjl.getSycs().intValue()) && "U".equals(hyjl.getStu())) {
                        hyjl.setSd(LocalDate.now());
                        hyjl.setEd(LocalDate.now().plusDays(hyjl.getZq()));
                        hyjl.setStu("R");
                        hyjlService.updateById(hyjl);
                    }

                    while (skjls.size() > 0) {
                        if (hyjl.getSycs().intValue() > 0) {
                            Akechengskjl akechengskjl = skjls.removeFirst();
                            akechengskjl.setHyjlid(hyjl.getHyjlid());
                            hyjl.setSycs(hyjl.getSycs() - 1);
                            bm.setSjzfje(bm.getSjzfje() - dj.intValue());
                            bm.setSyhycs(bm.getSyhycs() + 1);
                            toSkjls.add(akechengskjl);
                        } else {
                            hyjl.setStu("F");
                            break;
                        }
                    }

                    hyjlService.updateById(hyjl);

                    if (skjls.size() == 0) {
                        break;
                    }


                }
            } else {
                toSkjls.addAll(skjls);
            }

            skjlService.saveBatch(toSkjls);

            if (bm.getSjzfje() > 0) {

                /* 余额充足，不支付 */
                if (bm.getSjzfje() <= amount.getAmount()) {
                    amount.setAmount(amount.getAmount() - bm.getSjzfje());
                    bm.setYezfje(bm.getSjzfje());
                    bm.setSjzfje(0);
                    bm.setPflg(true);

                    /* 余额不充足，支付 */
                } else {
                    bm.setSjzfje(bm.getSjzfje() - amount.getAmount());
                    bm.setYezfje(amount.getAmount());
                    amount.setAmount(0);
                    PrepayWithRequestPaymentResponse prepayData =
                            wxAppPayBean.jsapi(
                                    bm.getBmid(),
                                    "报名订单",
                                    "/notice-url/" + bm.getBmid(),
                                    bm.getSjzfje(),
                                    client.getOpenid(),
                                    "",
                                    appid
                            );
                    String prepayId = prepayData.getPackageVal().split("=")[1];
                    bm.setPrepaydata(JSONObject.toJSONString(prepayData));
                    bm.setPrepayid(prepayId);
                }

                amountService.updateById(amount);
            }

            if (ybrs < zdrs) {
                bm.setStu("B");
            } else if (ybrs >= zdrs) {
                bm.setStu("P");
                bm.setSort(ybrs - zdrs + 1);
            }
            ybrs++;
            akecheng.setYbrs(ybrs);
            kechengService.updateById(akecheng);

            if (StringUtils.hasLength(client.getFromid()) && !client.getTgflg()) {

                Client fromClient = clientService.getById(client.getFromid());

                Integer ruleid = fromClient.getTgcount() % 3 + 1;
                fromClient.setTgcount(fromClient.getTgcount() + 1);
                clientService.updateById(fromClient);

                JSONObject ruleObj = cache.getJSONObject("FXRULE");
                Afxrule rule = ruleObj.getObject(String.valueOf(ruleid), Afxrule.class);

                Afxjl afxjl = new Afxjl();
                afxjl.setFxjlid(StringGenerator.getID("FX"));
                afxjl.setBmid(bm.getBmid());
                afxjl.setCt(LocalDateTime.now());
                afxjl.setTqper(rule.getTqper());
                afxjl.setAmount(bm.getPrice());
                afxjl.setFxje(new BigDecimal(bm.getPrice()).multiply(new BigDecimal(rule.getTqper())).intValue());
                afxjl.setClientid(clientid);
                afxjl.setFxjlid(bm.getMdjlid());
                afxjl.setFxclientid(fromClient.getClientid());
                afxjl.setStu("T");
                afxjl.setLevel(rule.getLevel());
                fxjlService.save(afxjl);

                bm.setFxjlid(afxjl.getFxjlid());
                bm.setFxje(afxjl.getFxje());

            }

            clientbmService.save(bm);
            param.put("aclientbm", bm);

            asyncService.runScheduler(() -> {
                synchronized (bm.getBmid().intern()) {
                    Aclientbm aclientbmCheck = clientbmService.getById(bm.getBmid());
                    if (!aclientbmCheck.getPflg()) {
                        cancelZyBm(aclientbmCheck);
                        return "未支付，报名取消";
                    }
                    return "已支付，报名成功";
                }

            }, 2, "报名支付核减：【"+bm.getBmid()+"】");
        }

        return param;

    }

    @Transactional
    public void payZyBmAfter(String bmid) {
        Aclientbm aclientbm = clientbmService.getById(bmid);
        aclientbm.setPflg(true);
        String kcid = aclientbm.getKcid();

        synchronized (kcid.intern()) {
            Akecheng akecheng = kechengService.getById(kcid);
            Integer ybrs = akecheng.getYbrs();
            Integer zdrs = akecheng.getZdrs();

            if (ybrs < zdrs) {
                aclientbm.setStu("B");
            } else if (ybrs >= zdrs) {
                aclientbm.setStu("P");
                aclientbm.setSort(ybrs - zdrs + 1);
            }
            akecheng.setYbrs(ybrs++);
            clientbmService.updateById(aclientbm);
            kechengService.updateById(akecheng);
        }

    }

    /**
     * 报名详细查询 硕哥
     * @param param
     * @return
     */
    public JSONObject getBm(JSONObject param) {

        String bmid = param.getString("bmid");
        if (!StringUtils.hasLength(bmid)) {
            throw new SystemException("报名id必须指定");
        }
        //报名信息
        //报名表
        Aclientbm aclientbm = clientbmService.getById(bmid);
        param.put("aclientbm", aclientbm);
        //客户表
        Client aclient = clientService.getById(aclientbm.getClientid());
        param.put("aclient", aclient);
        //教练表
        Ajiaolian ajiaolian = jiaolianService.getById(aclientbm.getJlid());
        param.put("ajiaolian", ajiaolian);
        //课程表
        Akecheng akecheng = kechengService.getById(aclientbm.getKcid());
        param.put("akecheng", akecheng);
        //课程item表
        QueryWrapper<Akechengitem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("kcid", aclientbm.getKcid());
        AkechengitemMapper akechengitemMapper = (AkechengitemMapper) kechengItemService.getBaseMapper();
        List<JSONObject> akechengitems = akechengitemMapper.getRoomAndStoreWithKcItem(queryWrapper);
        param.put("akechengitems", akechengitems);

        QueryWrapper<Ajlpj> pjqw = new QueryWrapper<>();
        pjqw.eq("bmid", aclientbm.getBmid());
        pjqw.eq("kcid", aclientbm.getKcid());
        pjqw.eq("jlid", aclientbm.getJlid());
        pjqw.eq("clientid", aclientbm.getClientid());

        Ajlpj ajlpj = ajlpjService.getOne(pjqw, false);
        param.put("ajlpj", ajlpj);

        if(StringUtils.hasLength(aclientbm.getFxjlid())) {
            Afxjl afxjl = fxjlService.getById(aclientbm.getFxjlid());
            param.put("afxjl", afxjl);
            Client fromClient = clientService.getById(afxjl.getFxclientid());
            param.put("fromclient", fromClient);
        }

        return param;
    }

    private Aclientbm cancelBm(Aclientbm aclientbm) {

        Client client = clientService.getById(aclientbm.getClientid());
        Ajiaolian ajiaolian = jiaolianService.getById(aclientbm.getJlid());
        synchronized (aclientbm.getKcid().intern()) {
            aclientbm.setStu("C");
            clientbmService.updateById(aclientbm);

            Amount jlAmount = amountService.getById(ajiaolian.getOpenid());
            Amount xyAmount = amountService.getById(client.getOpenid());
            xyAmount.setAmount(xyAmount.getAmount().intValue() + aclientbm.getSjzfje() + aclientbm.getYezfje());
            amountService.updateById(xyAmount);

            QueryWrapper<Akechengskjl> skjlqw = new QueryWrapper<>();
            skjlqw.in("bmid", aclientbm.getBmid());
            List<Akechengskjl> skjls = skjlService.list(skjlqw);
            skjls.forEach(skjl -> {
                if (StringUtils.hasLength(skjl.getHyjlid())) {
                    Ahyjl ahyjl = hyjlService.getById(skjl.getHyjlid());
                    ahyjl.setSycs(ahyjl.getSycs() + 1);
                    hyjlService.updateById(ahyjl);
                }
            });
            skjlService.remove(skjlqw);

            QueryWrapper<Aclientbm> bmqw = new QueryWrapper<>();
            bmqw.eq("kcid", aclientbm.getKcid());
            bmqw.eq("stu", "P");
            bmqw.gt("sort", 0);
            bmqw.orderByAsc("sort");
            List<Aclientbm> bms = clientbmService.list(bmqw);

            if (null != bms && bms.size() > 0) {
                for (int index  = 0; index < bms.size(); index++) {
                    Aclientbm bm = bms.get(index);
                    if (index == 0) {
                        bm.setStu("B");
                        bm.setSort(0);
                    } else {
                        bm.setSort(index - 1);
                    }
                }
                clientbmService.saveBatch(bms);
            }

            Akecheng akecheng = kechengService.getById(aclientbm.getKcid());
            Integer ybrs = akecheng.getYbrs();
            ybrs--;
            akecheng.setYbrs(ybrs);
            kechengService.updateById(akecheng);

            if (StringUtils.hasLength(aclientbm.getFxjlid())) {
                fxjlService.removeById(aclientbm.getFxjlid());
            }

        }

        return aclientbm;
    }

    private Aclientbm cancelZyBm(Aclientbm aclientbm) {

        Client client = clientService.getById(aclientbm.getClientid());
        Ajiaolian ajiaolian = jiaolianService.getById(aclientbm.getJlid());
        synchronized (aclientbm.getKcid().intern()) {
            aclientbm.setStu("C");
            clientbmService.updateById(aclientbm);

            Amount jlAmount = amountService.getById(ajiaolian.getOpenid());
            Amount xyAmount = amountService.getById(client.getOpenid());
            xyAmount.setAmount(xyAmount.getAmount().intValue() + aclientbm.getSjzfje() + aclientbm.getYezfje());
            amountService.updateById(xyAmount);

            QueryWrapper<Akechengskjl> skjlqw = new QueryWrapper<>();
            skjlqw.in("bmid", aclientbm.getBmid());
            List<Akechengskjl> skjls = skjlService.list(skjlqw);
            skjls.forEach(skjl -> {
                if (StringUtils.hasLength(skjl.getHyjlid())) {
                    Ahyjl ahyjl = hyjlService.getById(skjl.getHyjlid());
                    ahyjl.setSycs(ahyjl.getSycs() + 1);
                    hyjlService.updateById(ahyjl);
                }
            });
            skjlService.remove(skjlqw);

            QueryWrapper<Aclientbm> bmqw = new QueryWrapper<>();
            bmqw.eq("kcid", aclientbm.getKcid());
            bmqw.eq("stu", "P");
            bmqw.gt("sort", 0);
            bmqw.orderByAsc("sort");
            List<Aclientbm> bms = clientbmService.list(bmqw);

            if (null != bms && bms.size() > 0) {
                for (int index  = 0; index < bms.size(); index++) {
                    Aclientbm bm = bms.get(index);
                    if (index == 0) {
                        bm.setStu("B");
                        bm.setSort(0);
                    } else {
                        bm.setSort(index - 1);
                    }
                }
                clientbmService.saveBatch(bms);
            }

            Akecheng akecheng = kechengService.getById(aclientbm.getKcid());
            Integer ybrs = akecheng.getYbrs();
            ybrs--;
            akecheng.setYbrs(ybrs);
            kechengService.updateById(akecheng);

            if (StringUtils.hasLength(aclientbm.getFxjlid())) {
                fxjlService.removeById(aclientbm.getFxjlid());
            }

        }

        return aclientbm;
    }

    @Transactional
    public JSONObject cancelBm(JSONObject param) {
        String bmid = param.getString("bmid");
        if (!StringUtils.hasLength(bmid)) {
            throw new SystemException("报名id必须指定");
        }

        Aclientbm aclientbm = clientbmService.getById(bmid);

        if (!"P".equals(aclientbm.getStu()) && !"B".equals(aclientbm.getStu())) {
            throw new SystemException("当前报名的课程已经开始，无法取消。");
        }

        aclientbm = this.cancelBm(aclientbm);
        param.put("aclientbm", aclientbm);

        return param;
    }

    @Transactional
    public JSONObject cancelZyBm(JSONObject param) {
        String bmid = param.getString("bmid");
        if (!StringUtils.hasLength(bmid)) {
            throw new SystemException("报名id必须指定");
        }

        Aclientbm aclientbm = clientbmService.getById(bmid);

        if (!"P".equals(aclientbm.getStu()) && !"B".equals(aclientbm.getStu())) {
            throw new SystemException("当前报名的课程已经开始，无法取消。");
        }

        aclientbm = this.cancelZyBm(aclientbm);
        param.put("aclientbm", aclientbm);

        return param;
    }

    /**
     * 新增充值  颖姐（学员端充值）
     * @param param
     * @return
     */
    public JSONObject newCz(JSONObject param) {
        Aclientcz aclientcz = param.getObject("aclientcz", Aclientcz.class);
        aclientcz.setCzid(StringGenerator.getID("CZJL"));
        aclientcz.setCt(LocalDateTime.now());
        aclientcz.setPflg(false);

        if (!StringUtils.hasLength(aclientcz.getOpenid())) {
            throw new SystemException("学员必须指定");
        }

        /* 预支付单，用于发起微信支付 */
        PrepayWithRequestPaymentResponse prepayData =
                wxAppPayBean.jsapi(
                        aclientcz.getCzid(),
                        "充值订单",
                        "/notice-url/"+aclientcz.getCzid(),
                        aclientcz.getAmount(),
                        aclientcz.getOpenid(),
                        "",
                        appid
                );
        String prepayId = prepayData.getPackageVal().split("=")[1];
        aclientcz.setPrepayid(prepayId);
        aclientcz.setPrepaydata(JSONObject.toJSONString(prepayData));
        clientczService.save(aclientcz);
        param.put("aclientcz", aclientcz);
        return param;
    }

    @Transactional
    public void payCzAfter(String czid) {
        Aclientcz aclientcz = clientczService.getById(czid);

        synchronized (aclientcz.getOpenid().intern()) {
            aclientcz.setPflg(true);
            clientczService.updateById(aclientcz);

            Amount amount = amountService.getById(aclientcz.getOpenid());
            amount.setAmount(amount.getAmount() + aclientcz.getAmount());
            amountService.updateById(amount);
        }
    }

    /**
     * 学员分页查询 颖姐(平台端学员列表)
     * @param param
     * @return
     */
    public JSONObject getXysByPage(JSONObject param) {
        Integer current = param.getInteger("current");
        Integer size = param.getInteger("size");

        if(current == null || current < 0){
            current = 1;
        }

        if(size == null || size < 0){
            size = 16;
        }

        //构建分页
        IPage<Client> page = new Page<Client>(current, size);

        //构建条件
        QueryWrapper<Client> qwxypage = new QueryWrapper<>();

        String nc = param.getString("nc");
        if(StringUtils.hasLength(nc)){
            qwxypage.like("nc", nc);
        }

        Integer age = param.getInteger("age");
        if(age != null && age > 0){
            qwxypage.eq("age", age);
        }

        Boolean sex = param.getBoolean("sex");
        if (sex != null) {
            qwxypage.eq("sex", sex);
        }

        JSONArray clientids = param.getJSONArray("clientids");
        if (null != clientids && clientids.size() > 0) {
            qwxypage.in("clientid", clientids);
        }

        page = clientService.page(page, qwxypage);
        param.put("clientspage", page);
        return param;
    }

    /**
     * 学员详细查询 颖姐
     * @param param
     * @return
     */
    public JSONObject getXy(JSONObject param) {

        String clientid = param.getString("clientid");
        if(!StringUtils.hasLength(clientid)){
            throw new SystemException("学员id必须指定");
        }


        Client client = clientService.getById(clientid);
        param.put("client", client);
        param.put("amount", amountService.getById(client.getOpenid()));

        Client clientfrom = clientService.getById(client.getFromid());
        param.put("clientfrom", clientfrom);

        QueryWrapper<Aclientcz> qw = new QueryWrapper<>();
        qw.eq("openid", client.getOpenid());

        QueryWrapper<Ajiaolian> jqw = new QueryWrapper<>();
        jqw.eq("clientid", client.getClientid());
        jqw.eq("openid", client.getOpenid());
        Ajiaolian ajiaolian = ajiaolianService.getOne(jqw);
        param.put("ajiaolian", ajiaolian);

        QueryWrapper<Adz> dqw = new QueryWrapper<>();
        dqw.eq("clientid", client.getClientid());
        dqw.eq("openid", client.getOpenid());
        Adz adz = adzService.getOne(dqw);
        param.put("adz", adz);

        param.put("aclientczs", clientczService.list(qw));



        QueryWrapper<Aclientbm> qwbm = new QueryWrapper<>();
        qwbm.eq("clientid", clientid);
        qwbm.eq("pflg", true);
        param.put("bmnumber", clientbmService.count(qwbm));

        QueryWrapper<Aclienttq> qwtq = new QueryWrapper<>();
        qwtq.eq("clientid", clientid);
        param.put("tqnumber", aclienttqService.count(qwtq));

        QueryWrapper<Afxjl> qwfx = new QueryWrapper<>();
        qwfx.eq("fxclientid", clientid);
        param.put("fxnumber", fxjlService.count(qwfx));

        QueryWrapper<Akechengskjl> qwskjl = new QueryWrapper<>();

        return param;
    }

    /**
     * 修改学员 雷哥
     * @param param
     * @return
     */
    public JSONObject updateXy(JSONObject param) {
        Client client = param.getObject("client", Client.class);
        if(!StringUtils.hasLength(client.getClientid())){
            throw new SystemException("学员id不能为空");
        }
        clientService.updateById(client);

        QueryWrapper<Ajiaolian> jqw = new QueryWrapper<>();
        jqw.eq("clientid", client.getClientid());
        jqw.eq("openid", client.getOpenid());
        Ajiaolian ajiaolian = ajiaolianService.getOne(jqw);
        ajiaolian.setJlname(client.getNc());
        ajiaolian.setCover(client.getHeadimg());
        ajiaolian.setTx(client.getTx());
        ajiaolian.setTel(client.getTel());
        ajiaolianService.updateById(ajiaolian);


        QueryWrapper<Adz> dqw = new QueryWrapper<>();
        dqw.eq("clientid", client.getClientid());
        dqw.eq("openid", client.getOpenid());
        Adz adz = adzService.getOne(dqw);
        adz.setDname(client.getNc());
        adz.setCover(client.getHeadimg());
        adz.setTx(client.getTx());
        adz.setTel(client.getTel());
        adzService.updateById(adz);

        param.put("client", client);
        param.put("ajiaolian", ajiaolian);
        param.put("adz", adz);
        return param;
    }


    /**
     * 会员分页查询 骏哥
     * @param param
     * @return
     */
    public JSONObject getHysByPage(JSONObject param) {

        Integer current = param.getInteger("current");
        Integer size = param.getInteger("size");

        if (null == current || current < 0) {
            current = 1;
        }

        if (null == size || size < 0) {
            size = 16;
        }

        IPage<JSONObject> page = new Page<JSONObject>(current, size);

        QueryWrapper<JSONObject> qw = new QueryWrapper<>();

        String jlid = param.getString("jlid");
        if (StringUtils.hasLength(jlid)) {
            qw.eq("ahyjl.jlid", jlid);
        }

        String hylxid = param.getString("hylxid");
        if (StringUtils.hasLength(hylxid)) {
            qw.eq("ahyjl.hylxid", hylxid);
        }

        String clientid = param.getString("clientid");
        if (StringUtils.hasLength(clientid)) {
            qw.eq("ahyjl.clientid", clientid);
        }
        String hlname = param.getString("hlname");
        String jlname = param.getString("jlname");
        String nc = param.getString("nc");
        boolean hasSearchCondition = StringUtils.hasLength(hlname) || StringUtils.hasLength(jlname) || StringUtils.hasLength(nc);
        if (hasSearchCondition){
            qw.and(qww ->{
                if (StringUtils.hasLength(hlname)) {
                    qww.like("ahylx.hlname", hlname);
                }
            }).or(qww ->{
                if (StringUtils.hasLength(jlname)) {
                    qww.like("ajiaolian.jlname", jlname);
                }
            }).or(qww ->{
                if (StringUtils.hasLength(nc)) {
                    qww.like("client.nc", nc);
                }
            });
        }

        AhyjlMapper ahyjlMapper = (AhyjlMapper) hyjlService.getBaseMapper();

        page = ahyjlMapper.getHyWithHylxByPage(page,qw);
        param.put("ahyjls", page);
        return param;
    }

    /**
     * 会员查询 骏哥
     * @param param
     * @return
     */
    public JSONObject getHys(JSONObject param) {
        QueryWrapper<JSONObject> qw = new QueryWrapper<>();

        String jlid = param.getString("jlid");
        if (StringUtils.hasLength(jlid)) {
            qw.eq("ahyjl.jlid", jlid);
        }

        String hylxid = param.getString("hylxid");
        if (StringUtils.hasLength(hylxid)) {
            qw.eq("ahyjl.hylxid", hylxid);
        }

        String clientid = param.getString("clientid");
        if (StringUtils.hasLength(clientid)) {
            qw.eq("ahyjl.clientid", clientid);
        }

        String hyjlid = param.getString("hyjlid");
        if (StringUtils.hasLength(hyjlid)) {
            qw.eq("ahyjl.hyjlid", hyjlid);
        }

        if (StringUtils.hasLength(param.getString("hlname")) &&
                StringUtils.hasLength(param.getString("jlname")) &&
                StringUtils.hasLength(param.getString("nc"))) {
            qw.or(qww -> {
                String hlname = param.getString("hlname");
                if (StringUtils.hasLength(hlname)) {
                    qww.like("ahylx.hlname", hlname);
                }
            }).or(qww -> {
                String jlname = param.getString("jlname");
                if (StringUtils.hasLength(jlname)) {
                    qww.like("ajiaolian.jlname", jlname);
                }
            }).or(qww -> {
                String nc = param.getString("nc");
                if (StringUtils.hasLength(nc)) {
                    qww.like("client.nc", nc);
                }
            });
        }
        //调用mapper
        AhyjlMapper ahyjlMapper = (AhyjlMapper) hyjlService.getBaseMapper();
        List<JSONObject> hyWithHylx = ahyjlMapper.getHyWithHylx(qw);
        param.put("ahyjls", hyWithHylx);

        return param;
    }
    /**
    * 会员退款查询
    */
    @Transactional
    public JSONObject hyRefund(JSONObject param) {

        String hyjlid = param.getString("hyjlid");
        Ahyjl ahyjl = hyjlService.getById(hyjlid);
        boolean wks = "U".equals(ahyjl.getStu());
        boolean wtk = "U".equals(ahyjl.getTkflg());
        boolean x = !wks || !wtk;
        if(x) {
            throw new SystemException("当前会员已使用，不满足退款条件");
        }

        if (!ahyjl.getPflg() && ahyjl.getYezfje() == 0) {
            throw new SystemException("尚未支付的会员无法退款");
        }

        Client client = clientService.getById(ahyjl.getClientid());
        Amount amount = amountService.getById(client.getOpenid());
        amount.setAmount(amount.getAmount().intValue() + ahyjl.getYezfje() + ahyjl.getAmount());
        amountService.updateById(amount);
        ahyjl.setTkflg("J");
        hyjlService.updateById(ahyjl);
        param.put("ahyjl", ahyjl);
        return param;
    }

    /**
     * 会员详细查询 成哥
     * @param param
     * @return
     */
    public JSONObject getHyjl(JSONObject param) {

        String hyjlid = param.getString("hyjlid");
        if(!StringUtils.hasLength(hyjlid)){
            throw new SystemException("会员jlid必须指定");
        }

        Ahyjl ahyjl = hyjlService.getById(hyjlid);
        param.put("ahyjl", ahyjl);

        Ahylx ahylx = iAhylxService.getById(ahyjl.getHylxid());
        param.put("ahylx", ahylx);

        Ajiaolian ajiaolian = jiaolianService.getById(ahyjl.getJlid());
        param.put("ajiaolian", ajiaolian);

        Client client = clientService.getById(ahyjl.getClientid());
        param.put("client", client);

        return param;
    }

    /**
     * 学员充值分页查询 硕哥
     * @param param
     * @return
     */
    public JSONObject getCzByPage(JSONObject param) {

        Integer current = param.getInteger("current");
        Integer size = param.getInteger("size");

        if (null == current || current < 0) {
            current = 1;
        }

        if (null == size || size < 0) {
            size = 16;
        }

        IPage<JSONObject> page = new Page<JSONObject>(current, size);

        QueryWrapper<JSONObject> qw = new QueryWrapper<>();
        String clientid = param.getString("clientid");
        if(StringUtils.hasLength(clientid)){
            qw.eq("client.clientid",clientid);
        }
        AclientczMapper aclientczMapper = (AclientczMapper) clientczService.getBaseMapper();
        page = aclientczMapper.getCzsWithXyByPage(page, qw);
        param.put("czbypage",page );
        return param;
    }


    public JSONObject getFxjlByPage(JSONObject param) {

        Integer current = param.getInteger("current");
        Integer size = param.getInteger("size");

        if (null == current || current < 0) {
            current = 1;
        }

        if (null == size || size < 0) {
            size = 16;
        }

        IPage<JSONObject> page = new Page<JSONObject>(current, size);

        QueryWrapper<Afxjl> qw = new QueryWrapper<>();
        String fxclientid = param.getString("fxclientid");
        if(StringUtils.hasLength(fxclientid)){
            qw.eq("fxclientid", fxclientid);
        }

        String clientid = param.getString("clientid");
        if(StringUtils.hasLength(clientid)){
            qw.eq("clientid", clientid);
        }

        String jlid = param.getString("jlid");
        if(StringUtils.hasLength(jlid)){
            qw.eq("jlid", jlid);
        }

        AfxjlMapper afxjlMapper = (AfxjlMapper) fxjlService.getBaseMapper();
        page = afxjlMapper.getFxjlWithClandJlByPage(page, qw);
        param.put("afxjls", page);
        return param;
    }

    public JSONObject getFxjlByList(JSONObject param) {

        QueryWrapper<Afxjl> qw = new QueryWrapper<>();
        String fxclientid = param.getString("fxclientid");
        if(StringUtils.hasLength(fxclientid)){
            qw.eq("fxclientid", fxclientid);
        }

        String clientid = param.getString("clientid");
        if(StringUtils.hasLength(clientid)){
            qw.eq("clientid", clientid);
        }

        String jlid = param.getString("jlid");
        if(StringUtils.hasLength(jlid)){
            qw.eq("jlid", jlid);
        }

        AfxjlMapper afxjlMapper = (AfxjlMapper) fxjlService.getBaseMapper();
        List<JSONObject> afxjls = afxjlMapper.getFxjlWithClandJlByList(qw);
        param.put("afxjls", afxjls);
        return param;
    }

}



